package com.xuantu.pattern.create.factory;

/**
 * 工厂方法
 * 意图：定义一个用于创建对象的接口，让子类决定实例化哪一个类。
 * Factory Method使一个类实例化延迟到其子类。
 * 开关原则
 * 
 * 与简单工厂不同在于具体的实现由客户端选择
 * 
 * @author fengzp
 *
 */
public class FactoryMethod {
		
	/**
	 * 操作抽象类
	 * @author fengzp
	 *
	 */
	abstract class Operator {
		private double num1 = 0;
		private double num2 = 0;

		public double getNum1() {
			return num1;
		}

		public void setNum1(double num1) {
			this.num1 = num1;
		}

		public double getNum2() {
			return num2;
		}

		public void setNum2(double num2) {
			this.num2 = num2;
		}

		public abstract double getResult();

	}
	/**
	 * 加法操作
	 * @author fengzp
	 *
	 */
	class AddOperator extends Operator {

		@Override
		public double getResult() {
			return getNum1() + getNum2();
		}

	}
	/**
	 * 乘法操作
	 * @author fengzp
	 *
	 */
	class MulOperator extends Operator {

		@Override
		public double getResult() {
			return getNum1() * getNum2();
		}
	}
	
	/**
	 * 工厂
	 * @author fengzp
	 *
	 */
	interface IFactory {
		Operator createOperator();
	}
	
	/**
	 * 加法工厂
	 * @author fengzp
	 *
	 */
	class AddFactory implements IFactory {

		@Override
		public Operator createOperator() {
			return new AddOperator();
		}
		
	}
	/**
	 * 乘法工厂
	 * @author fengzp
	 *
	 */
	class MulFactory implements IFactory {

		@Override
		public Operator createOperator() {
			return new MulOperator();
		}
		
	}
	
	/**
	 * 客户端
	 * 如果想要求N的M次法，只要添加对象的操作类及工厂即可，满足开关原则
	 * @param args
	 */
	public static void main(String[] args) {
		IFactory factory = new FactoryMethod().new AddFactory();
		Operator operator = factory.createOperator();
		operator.setNum1(1);
		operator.setNum2(2);
		System.out.println(operator.getResult());
	}

}
